﻿using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Office.Interop.Outlook;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Outlook.WorkItems.Extension.Controls;
using Outlook.WorkItems.Extension.Managers.TeamBuildManager;
using Outlook.WorkItems.Extension.Manager.TeamBuildManager;

namespace Outlook.WorkItems.Extension.Addin.Forms
{
    public partial class CalendarLinkBuildForm : Form
    {
        private string _projectName;
        private string _serverUri;
        private SynchronizeBuildAction _action;
        private readonly MAPIFolder _folder;

        public CalendarLinkBuildForm()
        {
            InitializeComponent();
        }
        public CalendarLinkBuildForm(MAPIFolder folder)
        {
            InitializeComponent();
            btnOk.Enabled = false;

            _folder = folder;

            

            var linkExist = TeamBuildLinksManager.ContainsBuildCalendarLink(folder.EntryID);

            if (linkExist)
            {
                var link = TeamBuildLinksManager.GetBuildLink(folder.EntryID);
                _projectName = link.TeamProjectName;
                _serverUri = link.TeamServerUri;

                _action = link.SynchronizeBuildAction;

                

                var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(_serverUri));
                textBox1.Text = string.Format("{0} - {1}", tfs.Name, _projectName);
                var bserver = tfs.GetService<IBuildServer>();
                var definitions = bserver.QueryBuildDefinitions(_projectName);

                comboBox1.Items.Add("All Definitions");
                const int selectedIndex = 0;
                foreach (var item in definitions)
                {
                    comboBox1.Items.Add(item.Name);
                }
                comboBox1.SelectedIndex = selectedIndex;

                BindComboColorState();

                btnOk.Enabled = true;
                cbFailed.Enabled = true;
                cbInProgress.Enabled = true;
                cbPartialSucceeded.Enabled = true;
                cbStopped.Enabled = true;
                cbSucceeded.Enabled = true;
            }
            else
            {
                BindComboColorState();
                foreach (Category item in Globals.ThisAddIn.Application.Session.Categories)
                {
                    if (item.Color == OlCategoryColor.olCategoryColorGreen)
                        cbSucceeded.SelectedIndex = cbSucceeded.Items.IndexOf(item.Name);
                    if (item.Color == OlCategoryColor.olCategoryColorRed)
                        cbFailed.SelectedIndex = cbFailed.Items.IndexOf(item.Name);
                    if (item.Color == OlCategoryColor.olCategoryColorOrange)
                        cbPartialSucceeded.SelectedIndex = cbPartialSucceeded.Items.IndexOf(item.Name);
                    if (item.Color == OlCategoryColor.olCategoryColorBlack)
                        cbStopped.SelectedIndex = cbStopped.Items.IndexOf(item.Name);
                    if (item.Color == OlCategoryColor.olCategoryColorBlue)
                        cbInProgress.SelectedIndex = cbInProgress.Items.IndexOf(item.Name);
                }
            }
        }

        private void BindComboColorState()
        {
            var selectSucceededIndex = -1;
            var selectFailedIndex = -1;
            var selectPartialSucceededIndex = -1;
            var selectStoppedIndex = -1;
            var selectInProgressIndex = -1;
            foreach (Category item in Globals.ThisAddIn.Application.Session.Categories)
            {
                var succeededIndex = cbSucceeded.Items.Add(new ColorItem(item));
                var failedIndex = cbFailed.Items.Add(new ColorItem(item));
                var partialSucceededIndex = cbPartialSucceeded.Items.Add(new ColorItem(item));
                var stoppedIndex = cbStopped.Items.Add(new ColorItem(item));
                var inProgressIndex = cbInProgress.Items.Add(new ColorItem(item));

                if (_action != null && item.Name == _action.CategoryByStatus[BuildStatus.Succeeded])
                    selectSucceededIndex = succeededIndex;
                if (_action != null && item.Name == _action.CategoryByStatus[BuildStatus.Failed])
                    selectFailedIndex = failedIndex;
                if (_action != null && item.Name == _action.CategoryByStatus[BuildStatus.InProgress])
                    selectInProgressIndex = inProgressIndex;
                if (_action != null && item.Name == _action.CategoryByStatus[BuildStatus.Stopped])
                    selectStoppedIndex = stoppedIndex;
                if (_action != null && item.Name == _action.CategoryByStatus[BuildStatus.PartiallySucceeded])
                    selectPartialSucceededIndex = partialSucceededIndex;
            }

            cbSucceeded.SelectedIndex = selectSucceededIndex;
            cbFailed.SelectedIndex = selectFailedIndex;
            cbPartialSucceeded.SelectedIndex = selectPartialSucceededIndex;
            cbStopped.SelectedIndex = selectStoppedIndex;
            cbInProgress.SelectedIndex = selectInProgressIndex;
        }

        private void btnSelectTP_Click(object sender, EventArgs e)
        {
            try
            {
                using (var frm = new SelectTeamProjectForm())
                {
                    if (frm.ShowDialog() == DialogResult.OK)
                    {
                        comboBox1.Items.Clear();

                        Cursor = Cursors.WaitCursor;
                        _projectName = frm.ProjectName;
                        _serverUri = frm.ServerUri;
                        _action = new SynchronizeBuildAction();
                        
                        btnOk.Enabled = true;
                        cbFailed.Enabled = true;
                        cbInProgress.Enabled = true;
                        cbPartialSucceeded.Enabled = true;
                        cbStopped.Enabled = true;
                        cbSucceeded.Enabled = true;
                        var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(frm.ServerUri));
                        textBox1.Text = string.Format("{0} - {1}", tfs.Name, _projectName);
                        var bserver = tfs.GetService<IBuildServer>();
                        var definitions = bserver.QueryBuildDefinitions(_projectName);


                        comboBox1.Items.Add("All Definitions");
                        foreach (var item in definitions)
                        {
                            comboBox1.Items.Add(item.Name);
                        }
                        comboBox1.SelectedIndex = 0;
                    }
                }
            }
            catch (System.Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog(this);
                }
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            _action.CategoryByStatus.Clear();
            _action.CategoryByStatus.Add(BuildStatus.Failed, cbFailed.SelectedItem.ToString());
            _action.CategoryByStatus.Add(BuildStatus.Succeeded, cbSucceeded.SelectedItem.ToString());
            _action.CategoryByStatus.Add(BuildStatus.InProgress, cbInProgress.SelectedItem.ToString());
            _action.CategoryByStatus.Add(BuildStatus.PartiallySucceeded, cbPartialSucceeded.SelectedItem.ToString());
            _action.CategoryByStatus.Add(BuildStatus.Stopped, cbStopped.SelectedItem.ToString());

            _action.BuildDefinitionName = comboBox1.SelectedIndex > 0 ? comboBox1.SelectedItem.ToString() : "";

            var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(_serverUri));

            TeamBuildLinksManager.AddBuildLink(_folder.EntryID, _folder.StoreID, tfs.Name, _serverUri, _projectName, _action);
            DialogResult = DialogResult.OK;
            Close();
        }

        private void cbSucceeded_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            e.DrawFocusRectangle();

            var comboBoxItem = ((ComboBox)sender).Items[e.Index] as ColorItem;

            var bounds = e.Bounds;
            using (Brush textBrush = new SolidBrush(e.ForeColor))
            {
                var boundText = bounds;
                boundText.X += 15;
                using (var format = new StringFormat())
                {
                    format.LineAlignment = StringAlignment.Far;
                    format.Alignment = StringAlignment.Near;
                    if (comboBoxItem != null)
                        e.Graphics.DrawString(comboBoxItem.ToString(), comboBox1.Font, textBrush, boundText, format);
                }
            }
            Brush b = null;
            if (comboBoxItem != null)
            {
                switch (comboBoxItem.Category.Color)
                {
                    case OlCategoryColor.olCategoryColorBlack:
                        b = Brushes.Black;
                        break;
                    case OlCategoryColor.olCategoryColorBlue:
                        b = Brushes.Blue;
                        break;
                    case OlCategoryColor.olCategoryColorDarkBlue:
                        b = Brushes.DarkBlue;
                        break;
                    case OlCategoryColor.olCategoryColorDarkGray:
                        b = Brushes.DarkGray;
                        break;
                    case OlCategoryColor.olCategoryColorDarkGreen:
                        b = Brushes.DarkGreen;
                        break;
                    case OlCategoryColor.olCategoryColorDarkMaroon:
                        b = Brushes.Maroon;
                        break;
                    case OlCategoryColor.olCategoryColorDarkOlive:
                        b = Brushes.DarkOliveGreen;
                        break;
                    case OlCategoryColor.olCategoryColorDarkOrange:
                        b = Brushes.DarkOrange;
                        break;
                    case OlCategoryColor.olCategoryColorDarkPeach:
                        b = Brushes.PeachPuff;
                        break;
                    case OlCategoryColor.olCategoryColorDarkPurple:
                        b = Brushes.Purple;
                        break;
                    case OlCategoryColor.olCategoryColorDarkRed:
                        b = Brushes.DarkRed;
                        break;
                    case OlCategoryColor.olCategoryColorDarkSteel:
                        b = Brushes.White;
                        break;
                    case OlCategoryColor.olCategoryColorDarkTeal:
                        b = Brushes.White;
                        break;
                    case OlCategoryColor.olCategoryColorDarkYellow:
                        b = Brushes.Yellow;
                        break;
                    case OlCategoryColor.olCategoryColorGray:
                        b = Brushes.Gray;
                        break;
                    case OlCategoryColor.olCategoryColorGreen:
                        b = Brushes.Green;
                        break;
                    case OlCategoryColor.olCategoryColorMaroon:
                        b = Brushes.Maroon;
                        break;
                    case OlCategoryColor.olCategoryColorNone:
                        b = Brushes.White;
                        break;
                    case OlCategoryColor.olCategoryColorOlive:
                        b = Brushes.Olive;
                        break;
                    case OlCategoryColor.olCategoryColorOrange:
                        b = Brushes.Orange;
                        break;
                    case OlCategoryColor.olCategoryColorPeach:
                        b = Brushes.PeachPuff;
                        break;
                    case OlCategoryColor.olCategoryColorPurple:
                        b = Brushes.Purple;
                        break;
                    case OlCategoryColor.olCategoryColorRed:
                        b = Brushes.Red;
                        break;
                    case OlCategoryColor.olCategoryColorSteel:
                        b = Brushes.SteelBlue;
                        break;
                    case OlCategoryColor.olCategoryColorTeal:
                        b = Brushes.Teal;
                        break;
                    case OlCategoryColor.olCategoryColorYellow:
                        b = Brushes.Yellow;
                        break;
                    default:
                        break;
                }
                if (comboBoxItem.Category.Color == OlCategoryColor.olCategoryColorBlue)
                    b = Brushes.Blue;
                else if (comboBoxItem.Category.Color == OlCategoryColor.olCategoryColorOrange)
                    b = Brushes.Orange;
                else if (comboBoxItem.Category.Color == OlCategoryColor.olCategoryColorRed)
                    b = Brushes.Red;
                else if (comboBoxItem.Category.Color == OlCategoryColor.olCategoryColorGreen)
                    b = Brushes.Green;
            }

            if (b != null)
                e.Graphics.FillRectangle(b, bounds.X + 4, bounds.Y + 4, comboBox1.Font.Size, comboBox1.Font.Size);
        }
    }

    public class ColorItem
    {
        public Category Category { get; set; }
        public ColorItem(Category category)
        {
            Category = category;
        }

        public override string ToString()
        {
            return Category.Name;
        }
    }
}
